import json
import re
from django.contrib.auth import logout
from django.core.cache import cache
from django.http import JsonResponse
from django.views import View
from apps.areas.models import Area
from apps.areas.serializer import AreaSerializer, AddressSerializer
from apps.users.models import Address
from utils.center_user import LoginRequiredJSONMixin


# Create your views here.


# 省份数据的获取
class ProvinceView(View):
    def get(self, request):
        # 通过orm来获取数据   通过缓存来获取数据
        pro_list = cache.get('province_list')
        if not pro_list:
            set1 = Area.objects.filter(parent__isnull=True)
            # 通过定义的序列化来获取所有数据
            list1 = AreaSerializer(instance=set1, many=True)
            pro_list = list1.data
            cache.set('pro_list', pro_list, 30 * 24 * 3600)
        # 返回给前端数据
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'province_list': pro_list})






# 市区数据的获取
class SubsView(View):
    def get(self, request, pk):
        # 通过缓存来获取数据
        subs_data = cache.get(f'subs_data:{pk}')
        if not subs_data:
            # 通过省份来查找省份下面的市和县或区，通过外键来查找
            data = Area.objects.get(id=pk)
            # 通过外键关联来查询所有数据    通过级联操作来获取全部数据
            subs = data.subs.all()
            # 之后序列化器来获取数据
            sss = AreaSerializer(instance=subs, many=True)
            # 这是传给前端的数据
            subs_data = {
                'id': data.id,
                'name': data.name,
                'subs': sss.data
            }
            cache.set(f'sub_data:{pk}', subs_data, 30 * 24 * 3600)
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'sub_data': subs_data})


# 收货地址的添加和地址显示(获取数据)
class AddressView(LoginRequiredJSONMixin, View):
    def post(self, request):
        # 查询用户的地址数量 是多少
        count = Address.objects.filter(user=request.user).count()
        if count >= 20:
            return JsonResponse({"code": 400, "errmsg": "收货地址数量 达到上限"})
        # 不是表单数据，是JSON数据
        json_dict = json.loads(request.body.decode())
        json_dict['user_id'] = request.user.id
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({"code": 400, "errmsg": "参数mobile有误"})
        # if tel:
        #     if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
        #         return JsonResponse({"code": 400, "errmsg": "参数tel有误"})
        # if email:
        #     if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
        #         return JsonResponse({"code": 400, "errmsg": "参数email有误"})
        obj = AddressSerializer(data=json_dict)
        obj.is_valid(raise_exception=True)
        obj.save()
        if not request.user.default_address:
            request.user.default_address_id = obj.data.get('id')
            # 更新数据必须要 调用模型的save方法
            request.user.save()
        return JsonResponse({"code": 0, "errmsg": "Ok", "address": obj.data})

    def get(self, request):
        #获取用户下的地址
        user = request.user
        # 进行获取用户下的数据
        addresses = Address.objects.filter(user=user, is_deleted=False)
        # 然后再获取默认地址的id
        default_address_id = request.user.default_address_id
        # 再进行序列化的操作，，，来获取所有数据
        obj = AddressSerializer(instance=addresses, many=True)
        # 默认地址
        # 返回数据的时候会把默认地址id给带上
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'addresses': obj.data, 'default_address_id': default_address_id})


# 这是收货地址修改和删除操作
class AddressPUTView(LoginRequiredJSONMixin, View):
    def put(self, request, address_id):
        # 进行json解码
        json_dict = json.loads(request.body.decode())
        json_dict['user_id'] = request.user.id
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')
        # 校验参数      校验收获地址的参数是否符合规范
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': '参数mobile有误'})
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return JsonResponse({'code': 400, 'errmsg': '参数tel有误'})
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return JsonResponse({'code': 400, 'errmsg': '参数email有误'})

        # 进行获取数据
        count = Address.objects.filter(id=address_id)
        # 判断数据是否存在
        if count.count() == 0:
            return JsonResponse({'code': 400, 'errmsg': '不存在'})
        obj = count[0]
        # 进行序列化器的操作
        a1 = AddressSerializer(instance=obj, data=json_dict)
        # 进行校验
        a1.is_valid(raise_exception=True)
        # 进行保存
        a1.save()
        return JsonResponse({'code': 0, 'errmsg': '更新地址成功', 'address': a1.data})

    def delete(self, request, address_id):
        # 获取单个数据

        address = Address.objects.get(id=address_id)
        address.delete()

        # return JsonResponse({'code': 400, 'errmsg': '删除地址失败'})
        # 返回响应
        return JsonResponse({'code': 0, 'errmsg': 'ok'})




# 这是设置的默认地址
class DefaultAddressView(LoginRequiredJSONMixin, View):
    """设置默认地址"""
    def put(self, request, address_id):
        """设置默认地址"""
        try:
            # 接收参数,查询地址
            address = Address.objects.get(id=address_id, user=request.user)
            # 设置地址为默认地址
            request.user.default_address = address
            # request.user.default_address_id =address_id
            request.user.save()
        except:
            return JsonResponse({'code': 400, 'errmsg': '设置默认地址失败'})
        # 响应设置默认地址结果
        return JsonResponse({'code': 0, 'errmsg': '设置默认地址成功'})




# 这是修改账号密码的操作
class ChangePasswordView(LoginRequiredJSONMixin, View):
    def put(self, request):
        """实现修改密码逻辑"""
        # 接收参数
        dict = json.loads(request.body.decode())
        old_password = dict.get('old_password')
        new_password = dict.get('new_password')
        new_password2 = dict.get('new_password2')
        # 校验参数
        if not all([old_password, new_password, new_password2]):
            return JsonResponse({'code': 400, 'errmsg': '缺少必传参数'})
        result = request.user.check_password(old_password)
        if not result:
            return JsonResponse({'code': 400, 'errmsg': '原始密码不正确'})
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return JsonResponse({'code': 400, 'errmsg': '密码最少8位,最长20位'})
        if new_password != new_password2:
            return JsonResponse({'code': 400, 'errmsg': '两次输入密码不一致'})
        # 修改密码
        try:
            # 设置新的密码
            request.user.set_password(new_password)
            # 进行保存
            request.user.save()
        except:
            return JsonResponse({'code': 400, 'errmsg': '修改密码失败'})
        # 清理状态保持信息
        logout(request)
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        # 把原来的cookie给删掉
        response.delete_cookie('username')
        # # 响应密码修改结果：重定向到登录界面
        return response

# 这是收货地址标题的
class TitelView(LoginRequiredJSONMixin, View):
    """设置地址标题"""

    def put(self, request, address_id):
        """设置地址标题"""
        # 接收参数：地址标题
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        try:
            # 查询地址
            address = Address.objects.get(id=address_id)
            # 设置新的地址标题
            address.title = title
            # 保存新的地址标题
            address.save()
        except:
            return JsonResponse({'code': 400, 'errmsg': '设置地址标题失败'})

        # 4.响应删除地址结果
        return JsonResponse({'code': 0, 'errmsg': '设置地址标题成功'})

